using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Reflection;

namespace H2.NET.Common
{
    public class Pensieve
    {
        private Object _page = null;

        public Pensieve(Object page)
        {
            _page = page;
        }

        public void Save()
        {
            FieldInfo[] fields = _page.GetType().GetFields( BindingFlags.GetField | 
                                                            BindingFlags.Public |
                                                            BindingFlags.Instance);

            foreach (FieldInfo field in fields)
            {
                if (hasCustomAttributes(field))
                {
                    Type fieldCustomAttribute = field.GetCustomAttributes(false)[0].GetType();
                    SaveValue(field, fieldCustomAttribute);
                }
            }
        }

        private bool hasCustomAttributes(FieldInfo field)
        {
            return (field.GetCustomAttributes(false).Length > 0);
        }

        public void Retrieve()
        {
            FieldInfo[] fields = _page.GetType().GetFields( BindingFlags.GetField | 
                                                            BindingFlags.Public | 
                                                            BindingFlags.Instance);

            foreach (FieldInfo field in fields)
            {
                if (hasCustomAttributes(field))
                {
                    Type fieldCustomAttribute = field.GetCustomAttributes(false)[0].GetType();
                    RetrieveValue(field, fieldCustomAttribute);
                }
            }
        }

        private void SaveValue(FieldInfo field, Type fieldCustomAttribute)
        {
            object fieldVal = field.GetValue(_page);
            HttpContext context = HttpContext.Current;

            if (fieldCustomAttribute == typeof(SessionType))
            {
                context.Session[field.Name] = fieldVal;
            }
            else if (fieldCustomAttribute == typeof(ApplicationType))
            {
                context.Application[field.Name] = fieldVal;
            }
            else if (fieldCustomAttribute == typeof(CacheType))
            {
                    context.Cache[field.Name] = fieldVal;
            }

        }

        private void RetrieveValue(FieldInfo field, Type fieldCustomAttribute)
        {
            object fieldVal = null;
            HttpContext context = HttpContext.Current;

            if (fieldCustomAttribute == typeof(SessionType))
            {
                fieldVal = context.Session[field.Name];
            }
            else if (fieldCustomAttribute == typeof(ApplicationType))
            {
                fieldVal = context.Application[field.Name];
            }
            else if (fieldCustomAttribute == typeof(CacheType))
            {
                fieldVal = context.Cache[field.Name];
            }

            if (fieldVal != null)
            {
                field.SetValue(_page, fieldVal);
            }
        }
    }
}